ACKNOWLEDGEMENT Thanks to Roger Ivie for his contribution of the ASGB cross assembler. Roger Ivie ivie at cc dot usu dot edu And to Sebastian Riedel for updating and adding the various alternate instruction formats found in the SDCC implementation of the Gameboy assembler. Sebastian Riedel sdcc at basxto dot de
INTRODUCTION The Gameboy uses an 8-bit processor which is closely related to the 8080. It is usually described as a modified Z80, but may be more closely understood as an enhanced 8080; it has the 8080 register set and many, but not all, enhanced Z80 instructions. However, even this is not accurate, for the Gameboy also lacks some basic 8080 instructions (most annoyingly SHLD and LHLD). ASGB is based on ASZ80 and therefore uses the Z80 mnemonic set. GAMEBOY REGISTER SET AND CONDITIONS The following is a complete list of register designations and condition mnemonics: byte registers - a,b,c,d,e,h,l register pairs - af, bc, de, hl word registers - pc, sp C - carry bit set NC - carry bit clear NZ - zero bit clear Z - zero bit set GAMEBOY INSTRUCTION SET The following tables list all Gameboy mnemnoics recognized by the ASGB assembler. The designation [] refers to a required ad- dressing mode argument. The following list specifies the format for each addressing mode supported by ASGB: #data immediate data byte or word data n byte value rg a byte register a,b,c,d,e,h,l rp a register pair or 16-bit register bc,de,hl (hl) implied addressing or register indirect addressing (label) direct addressing label call/jmp/jr label The terms data, n, label, and address may all be expressions. Note that not all addressing modes are valid with every in- struction. Although official information is not, as far as I know, publically available for the Gameboy processor, many unof- ficial sources are available on the internet. .tile Directive Format: .tile /string/ or .tile ^/string/ where: string is a string of ascii characters taken from the set ' ', '.', '+', '*', '0', '1', '2', and '3'. The string must be a multiple of eight characters long. / / represent the delimiting characters. These delimiters may be any paired printing characters, as long as the characters are not contained within the string itself. If the delimiting characters do not match, the .tile directive will give the <q> error. The Gameboy displays information on the screen using a pro- grammable character set (referred to as "tiles" among Gameboy developers). The ASGB cross assembler has a processor-specific assembler directive to aid in the creation of the game's character set. Each character is created from an 8x8 grid of pixels, each pixel of which is composed of two bits. The .tile directive ac- cepts a single string argument which is processed to create the byte values corresponding to the lines of pixels in the character. The string argument must be some multiple of 8 characters long, and be one of these characters: ' ' or '0' - for the pixel value 00 '.' or '1' - for the pixel value 01 '+' or '2' - for the pixel value 10 '*' or '3' - for the pixel value 11 The .tile directive processes each 8-character group of its string argument to create the two-byte value corresponding to that line of pixels. The example in the popular extant litera- ture could be done using ASGB like this: 0000 7C 7C 1 .tile " ***** " 0002 00 C6 2 .tile "++ ++ " 0004 C6 00 3 .tile ".. .. " 0006 00 FE 4 .tile "+++++++ " 0008 C6 C6 5 .tile "** ** " 000A 00 C6 6 .tile "++ ++ " 000C C6 00 7 .tile ".. .. " 000E 00 00 8 .tile " " Or, using the synonym character set, as: 0010 7C 7C 10 .tile "03333300" 0012 00 C6 11 .tile "22000220" 0014 C6 00 12 .tile "11000110" 0016 00 FE 13 .tile "22222220" 0018 C6 C6 14 .tile "33000330" 001A 00 C6 15 .tile "22000220" 001C C6 00 16 .tile "11000110" 001E 00 00 17 .tile "00000000" Since .tile is perfectly willing to assemble multiple lines of a character at once (as long as it is given complete rows of pixels), it could even be done as: .tile " ***** ++ ++ .. .. +++++++ " .tile "** ** ++ ++ .. .. " Potentially Controversial Mnemonic Selection Although the Gameboy processor is based on the Z80, it does include some features which are not present in the Z80. The Z80 mnemonic set is not sufficient to describe these additional operations; mnemonics must be created for the new operations. The mnemonics ASGB uses are not the same as those used by other publically-available Gameboy assemblers. Auto-Indexing Loads - The Gameboy provides instructions to load or store the ac- cumulator indirectly via HL and then subsequently increment or decrement HL. ASGB uses the mnemonic 'ldd' for the instructions which decrement HL and 'ldi' for the instructions which incre- ment HL. Because the Gameboy lacks the Z80's block moves, the mnemonics are not otherwise needed by ASGB. ldd a,(hl) ldd (hl),a ldi a,(hl) ldi (hl),a Input and Output Operations - The Gameboy replaces the Z80's separate address space for I/O with a mechanism similar to the zero page addressing of pro- cessors such as the 6800 or 6502. All I/O registers in the Gameboy reside in the address range between 0xff00 and 0xffff. The Gameboy adds special instructions to load and store the ac- cumulator from and into this page of memory. The instructions are analogous to the Z80's in and out instructions and ASGB re- tains the 'in' and 'out' mnemonics for them. in a,(n) out (n),a in a,(c) out (c),a From ASGB's perspective, the RAM available from 0xff80 through 0xffff is composed of unused I/O locations rather than direct-page RAM. The 'stop' Instruction - The publicly available documentation for the Gameboy lists the 'stop' instruction as the two-byte instruction 10 00, and the other freely available Gameboy assemblers assemble it in that manner. NOTE 'stop' is actually just one byte long. There is a hardware bug on Gameboy Classic that causes the in- struction following a 'stop' instruction to be skipped under certain conditions. Nintendo apparently started to tell developers to always add a 'nop' after 'stop'. Inherent Instructions ccf cpl daa di ei nop halt rla rlca rra rrca scf reti stop | Recommended | Alternates | |===============|===============| | rla | rl a | | rlca | rlc a | | rra | rr a | | rrca | rrc a | |===============|===============| Implicit Operand Instructions | Recommended | Aliases | |===============|===============| | adc a,[] | adc [] | | add a,[] | add [] | | and a,[] | and [] | | cp a,[] | cp [] | | or a,[] | or [] | | sbc a,[] | sbc [] | | sub a,[] | sub [] | | xor a,[] | xor [] | |===============|===============| [] = a, b, c, d, e, h, l, (hl), or # Increment and Decrement Instructions dec [] inc [] [] = a, b, c, d, e, h, l, (hl), (be), (de), (hl+), (hl-), or sp Single Operand Instructions rl [] rlc [] rr [] rrc [] sla [] sra [] srl [] swap [] [] = a, b, c, d, e, h, l, or (hl) Load Instructions | Recommended | Aliases | |===============|===============| | ld a,[] | lda [] | | | ld [] | |===============|===============| [] = a, b, c, d, e, h, l, (c), (hl), (bc), (de), (hl+), (hl-), (address), or #data ld [1],[2] [1] = a, b, c, d, e, h, l, or (hl) [2] = a, b, c, d, e ,h, l, or (hl) except when [1] = (hl) and [2] = (hl) | Recommended | Aliases | |===============|===============| | ld hl,#data | lda hl,#data | | | | | | ldhl #data | |===============|===============| ld [],#data [] = bc, de, or sp ld a,[] ld [],a [] = (bc), (de), or (address) | Recommended | Aliases | |===============|===============| | ld a,(hl-) | ldd a,(hl) | | | | | | ld a,(hld) | | | lda (hld) | | | ld (hld) | | | lda (hl-) | | | ld (hl-) | |===============|===============| | ld (hl-),a | ldd (hl),a | | | | | | ld (hld),a | |===============|===============| | ld a,(hl+) | ldi a,(hl) | | | | | | ld a,(hli) | | | lda (hli) | | | ld (hli) | | | lda (hl+) | | | ld (hl+) | |===============|===============| | ld (hl+),a | ldi (hl),a | | | | | | ld (hli),a | |===============|===============| ld (address),sp ld sp,hl | Recommended | Aliases | |===============|===============| | ld hl,n(sp) | ldhl n(sp) | | | | | | ld hl,(sp)+n | | | ld hl,(sp+n) | | | ld hl,sp+n | | | | | | ldhl (sp)+n | | | ldhl (sp+n) | | | ldhl sp+n | |===============|===============| | ld hl,0(sp) | ld hl,(sp) | |===============|===============| | ldhl 0(sp) | ldhl (sp) | | | | | | ld hl,(sp+0) | | | ld hl,sp+0 | | | ld hl,sp | |===============|===============| Note: -128 <= n <= 127 Call/Return Instructions call C,label ret C call NC,label ret NC call Z,label ret Z call NZ,label ret NZ call label ret rst n Jump Instructions jp C,label jp NC,label jp Z,label jp NZ,label jp (hl) jp label jr C,label jr NC,label jr Z,label jr NZ,label jr label Bit Manipulation Instructions bit n,[] res n,[] set n,[] 0 <= n <= 7 [] = a, b, c, d, e, h, l, or (hl) Input and Output Instructions | Recommended | Aliases/Alternates | |===============|=======================| | ldh a,(n) | in a,(n) | | | | | | ld (n + 0xFF00) | | | lda (n + 0XFF00) | | | ld a,(n + 0xFF00) | |===============|=======================| | ldh a,(c) | in a,(c) | | | | | | ld (c) | | | lda (c) | | | ld a,(c) | |===============|=======================| | ldh (n),a | out n,a | | | | | | ld (n + 0xFF00),a | |===============|=======================| | ldh (c),a | out (c),a | | | | | | ld (c),a | |===============|=======================| Note: 0 <= n <= 255 Register Pair Instructions add hl,[] [] = bc, de, hl, or sp | Recommended | Aliases | |===============|===============| | add sp,#n | ld sp,#n(sp) | | | ld sp,n(sp) | | | | | | lda sp,#n(sp) | | | lda sp,n(sp) | |===============|===============| Note: -128 <= n <= 127 push [] pop [] [] = af, bc, de, or hl
... Exit the ASxxxx Documentation